package com.qianying.rbac.scanner;

import com.qianying.comment.CommonResult;
import com.qianying.entity.SysPermission;
import com.qianying.service.SysPermissionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 接口扫描器，用于扫描系统中的API接口信息并保存到数据库
 */
@Component
public class ApiScannerRunner implements ApplicationRunner {

    private final RequestMappingHandlerMapping handlerMapping;
    // 注入权限服务
    @Autowired
    private SysPermissionService sysPermissionService;

    /**
     * 构造函数注入
     */
    public ApiScannerRunner(RequestMappingHandlerMapping handlerMapping/*, SysPermissionService sysPermissionService*/) {
        this.handlerMapping = handlerMapping;
        // this.sysPermissionService = sysPermissionService;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
       /* // 获取所有处理器方法并按控制器类分组
        Map<Class<?>, List<HandlerMethod>> controllerMethods = handlerMapping.getHandlerMethods().values()
                .stream()
                .collect(Collectors.groupingBy(HandlerMethod::getBeanType));

        // 遍历所有控制器
        for (Map.Entry<Class<?>, List<HandlerMethod>> entry : controllerMethods.entrySet()) {
            Class<?> controllerClass = entry.getKey();
            List<HandlerMethod> methodList = entry.getValue();

            // 1. 获取Controller级别注解信息
            // 1.1 获取类级别@RequestMapping路径
            RequestMapping classRequestMapping = controllerClass.getAnnotation(RequestMapping.class);
            String classBasePath = getMappingPath(classRequestMapping);

            // 1.2 获取@Tag注解信息
            Tag classTag = controllerClass.getAnnotation(Tag.class);
            String tagName = classTag != null ? classTag.name() : "";
            String tagDescription = classTag != null ? classTag.description() : "";
            if (!isAdminPath(classBasePath)) {
                System.out.println("不是后端路径：" + classBasePath);
                continue;
            }
            // 打印控制器信息
            CommonResult<SysPermission> result = saveOrUpdatePermission(tagName, "", controllerClass.getName(),
                    classBasePath, tagDescription, null);
            if (!result.isSuccess()) {
                System.out.println("扫描接口错误：" + classRequestMapping);
                continue;
            }
            // 2. 遍历处理当前控制器的所有方法
            for (HandlerMethod handlerMethod : methodList) {
                // 2.1 获取方法基本信息
                String methodName = handlerMethod.getMethod().getName();

                // 2.2 获取方法级别请求注解信息（GetMapping/PostMapping等）
                String methodPath = "";
                Set<RequestMethod> requestMethods = new HashSet<>();

                // 处理各种HTTP方法注解
                if (handlerMethod.hasMethodAnnotation(GetMapping.class)) {
                    GetMapping getMapping = handlerMethod.getMethodAnnotation(GetMapping.class);
                    methodPath = getMappingPath(getMapping);
                    requestMethods.add(RequestMethod.GET);
                } else if (handlerMethod.hasMethodAnnotation(PostMapping.class)) {
                    PostMapping postMapping = handlerMethod.getMethodAnnotation(PostMapping.class);
                    methodPath = getMappingPath(postMapping);
                    requestMethods.add(RequestMethod.POST);
                } else if (handlerMethod.hasMethodAnnotation(PutMapping.class)) {
                    PutMapping putMapping = handlerMethod.getMethodAnnotation(PutMapping.class);
                    methodPath = getMappingPath(putMapping);
                    requestMethods.add(RequestMethod.PUT);
                } else if (handlerMethod.hasMethodAnnotation(DeleteMapping.class)) {
                    DeleteMapping deleteMapping = handlerMethod.getMethodAnnotation(DeleteMapping.class);
                    methodPath = getMappingPath(deleteMapping);
                    requestMethods.add(RequestMethod.DELETE);
                } else if (handlerMethod.hasMethodAnnotation(PatchMapping.class)) {
                    PatchMapping patchMapping = handlerMethod.getMethodAnnotation(PatchMapping.class);
                    methodPath = getMappingPath(patchMapping);
                    requestMethods.add(RequestMethod.PATCH);
                } else if (handlerMethod.hasMethodAnnotation(RequestMapping.class)) {
                    // 处理原生@RequestMapping注解
                    RequestMapping methodRequestMapping = handlerMethod.getMethodAnnotation(RequestMapping.class);
                    methodPath = getMappingPath(methodRequestMapping);
                    if (methodRequestMapping.method().length > 0) {
                        requestMethods.addAll(Arrays.asList(methodRequestMapping.method()));
                    }
                }

                // 设置默认请求方法
                if (requestMethods.isEmpty()) {
                    requestMethods.add(RequestMethod.GET);
                }

                // 2.3 拼接完整请求路径
                String fullPath = combinePaths(classBasePath, methodPath);

                // 2.4 获取@Operation注解信息
                Operation operation = handlerMethod.getMethodAnnotation(Operation.class);
                String opSummary = operation != null ? operation.summary() : "";
                String opDescription = operation != null ? operation.description() : "";

                saveOrUpdatePermission(opSummary, methodName, controllerClass.getName(),
                        fullPath, opDescription, result.getData().getId());

            }
        }

        System.out.println("\n✅ 接口扫描完成，已处理所有控制器和方法");*/
    }

    /**
     * 判断路径是否以admin开头
     * 支持两种格式: /admin/... 或 admin/...
     */
    private boolean isAdminPath(String path) {
        if (path == null || path.isEmpty()) {
            return false;
        }
        // 标准化路径（去除开头的斜杠）
        String normalizedPath = path.startsWith("/") ? path.substring(1) : path;
        // 判断是否以admin开头且后面跟斜杠或为完整单词
        return normalizedPath.startsWith("admin/") || normalizedPath.equals("admin");
    }

    /**
     * 从@RequestMapping注解中提取路径
     */
    private String getMappingPath(RequestMapping requestMapping) {
        if (requestMapping == null || requestMapping.value() == null || requestMapping.value().length == 0) {
            return "";
        }
        return requestMapping.value()[0];
    }

    /**
     * 从GetMapping注解中提取路径
     */
    private String getMappingPath(GetMapping getMapping) {
        if (getMapping == null || getMapping.value() == null || getMapping.value().length == 0) {
            return "";
        }
        return getMapping.value()[0];
    }

    /**
     * 从PostMapping注解中提取路径
     */
    private String getMappingPath(PostMapping postMapping) {
        if (postMapping == null || postMapping.value() == null || postMapping.value().length == 0) {
            return "";
        }
        return postMapping.value()[0];
    }

    /**
     * 从PutMapping注解中提取路径
     */
    private String getMappingPath(PutMapping putMapping) {
        if (putMapping == null || putMapping.value() == null || putMapping.value().length == 0) {
            return "";
        }
        return putMapping.value()[0];
    }

    /**
     * 从DeleteMapping注解中提取路径
     */
    private String getMappingPath(DeleteMapping deleteMapping) {
        if (deleteMapping == null || deleteMapping.value() == null || deleteMapping.value().length == 0) {
            return "";
        }
        return deleteMapping.value()[0];
    }

    /**
     * 从PatchMapping注解中提取路径
     */
    private String getMappingPath(PatchMapping patchMapping) {
        if (patchMapping == null || patchMapping.value() == null || patchMapping.value().length == 0) {
            return "";
        }
        return patchMapping.value()[0];
    }

    /**
     * 拼接类路径和方法路径
     */
    private String combinePaths(String classPath, String methodPath) {
        // 处理根路径情况
        if (classPath.isEmpty() && methodPath.isEmpty()) {
            return "/";
        }

        // 标准化类路径（去除末尾斜杠）
        String normalizedClassPath = classPath.endsWith("/")
                ? classPath.substring(0, classPath.length() - 1)
                : classPath;

        // 标准化方法路径（去除开头斜杠）
        String normalizedMethodPath = methodPath.startsWith("/")
                ? methodPath.substring(1)
                : methodPath;

        // 拼接路径
        if (normalizedClassPath.isEmpty()) {
            return "/" + normalizedMethodPath;
        }
        if (normalizedMethodPath.isEmpty()) {
            return normalizedClassPath;
        }
        return normalizedClassPath + "/" + normalizedMethodPath;
    }

    /**
     * 保存或更新权限信息
     */
    private CommonResult<SysPermission> saveOrUpdatePermission(String controllerName, String methodName, String className,
                                                               String requestMapping, String description, Long parentId) {
        SysPermission sysPermission = new SysPermission();
        sysPermission.setName(controllerName);
        sysPermission.setMethodName(methodName);
        sysPermission.setClassName(className);
        sysPermission.setRequestMapping(requestMapping);
        sysPermission.setDescription(description);
        sysPermission.setParentId(parentId);
        CommonResult res = sysPermissionService.saveOrUpdatePermission(sysPermission);
        return res;
    }
}

